package com.xoa.dev.workFlow.controller;


import com.xoa.dao.enclosure.AttachmentMapper;
import com.xoa.dao.workflow.FlowRunMapper;
import com.xoa.dev.workFlow.common.FormStyle;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.workflow.FlowRun;
import com.xoa.service.workflow.flowUtil.FlowUtilService;
import com.xoa.util.Convert;
import com.xoa.util.FileUploadUtil;
import com.xoa.util.ModuleEnum;
import com.xoa.util.ToJson;
import com.xoa.util.common.StringUtils;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

@Controller
@RequestMapping("/WorkFlowHtmlUtil")
public class WorkFlowHtmlUtilController {

    @Resource
    private FlowRunMapper flowRunMapper;

    @Resource
    private AttachmentMapper attachmentMapper;

    @Resource
    private FlowUtilService flowUtilService;


    @ResponseBody
    @RequestMapping("/htmlToWord")
    public ToJson<Attachment> htmlToWord(HttpServletRequest request, HttpServletResponse response, String html, Integer runId) {
        ToJson<Attachment> json = new ToJson<>();

        //因为word不识别隐藏元素，所以要剔除
        Document doc = Jsoup.parse(html);
        Elements elements = doc.select("div[style*=display: none]");
        elements.remove();
        html = doc.html();

        ByteArrayInputStream bais = null;
        OutputStream ostream = null;
        try {
            FlowRun flowRun = flowRunMapper.selectByRunId(runId);

            if(!StringUtils.checkNull(flowRun.getRunName())){
                flowRun.setRunName(flowRun.getRunName().replace(":","_").replace("|","_").replace("/","_").replace("\\","_"));
            }

            // 获取上传头 xoa/attach
            StringBuilder uploadHead = FileUploadUtil.getUploadHead();

            // 当前年月
            String ym = new SimpleDateFormat("yyMM").format(new Date());

            // 组织
            String company = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");

            // 时间戳数字串
            String attachID = String.valueOf(Math.abs((int) System.currentTimeMillis()));

            // 文件存储路径
            StringBuilder filePath = uploadHead.append(System.getProperty("file.separator")).
                    append(company).append(System.getProperty("file.separator")).
                    append("workflow").append(System.getProperty("file.separator")).
                    append(ym).append(System.getProperty("file.separator"));

            // 生成文件目录
            new File(filePath.toString()).mkdirs();

            String docFileName = "表单.doc";
            // 获得原始文件名
            if(flowRun!=null){
                docFileName = flowRun.getRunName()+".doc";
                try {
                    String runName = flowRun.getRunName();
                    String osName = System.getProperty("os.name");
                    int codeLength = runName.getBytes("UTF-8").length;
                    if(codeLength>230&&osName.toLowerCase().startsWith("linu")){//
                        String s = (new BASE64Encoder()).encodeBuffer(runName.getBytes(StandardCharsets.UTF_8));
                        String regEx=("[\\s\\\\/:\\*\\?\\\"<>\\|]");
                        docFileName=(Pattern.compile(regEx).matcher(s).replaceAll("").trim()).substring(0,100)+".doc";
                    }
                } catch (Exception e) {

                }
            }

            String printHtml = "<html><head>";
            // 特殊处理引入的样式
            // 获取webRoot路径
            String webRootPath = request.getSession().getServletContext().getRealPath("/");

            html =html.replace("<img src=\"/img/workflow.gif\" alt=\"\">","").
                    replace("<img src=\"/img/arrow_down.gif\" alt=\"\">","").
                    replace("<img style=\"margin-left: 5px;width: 18px;margin-bottom: 4px;\" src=\"/img/workflow/work/htbtn.png\">","");
            html = html.replace("/img", webRootPath + "ui/img");
            // 特殊处理htmlContent
            html = html.replace("<>","<div style='display:none'>");
            html = html.replace("</>","</div>");
            html = html.replace("&lt;&gt;","");

            printHtml = printHtml + FormStyle.HTML_PREVIEW_STYLE + "</head><body>" + html + "</body></html>";

            // 处理图片 设置图片路径地址为绝对路径地址 导出的图片需要用绝对路径地址
            Document parse = Jsoup.parse(printHtml);
            Elements imgs = parse.getElementsByTag("img");
            for(Element img:imgs){
                String src = img.attr("src");
                if(src.contains("xs?")) {
                    Attachment attachment = attachmentMapper.findByAttachId(Integer.parseInt(flowUtilService.getAttachParamValue(src, "AID")));
                    if(attachment!=null){
                        // 获取xoa路径地址
                        StringBuilder imgRealPath = FileUploadUtil.getUploadHead();;
                        // 拼接相对路径
                        imgRealPath.append(System.getProperty("file.separator"))
                                .append("xoa" + (String) request.getSession().getAttribute("loginDateSouse")).append(System.getProperty("file.separator"))
                                .append(flowUtilService.getAttachParamValue(src,"MODULE")).append(System.getProperty("file.separator"))
                                .append(attachment.getYm()).append(System.getProperty("file.separator"))
                                .append(attachment.getAttachId()).append(".").append(attachment.getAttachName());
                        // 替换图片路径为相对路径
                        img.attr("src",imgRealPath.toString());
                    }
                }
            }
            printHtml = parse.toString();
            byte b[] = printHtml.getBytes();
            bais = new ByteArrayInputStream(b);//将字节数组包装到流中
            //生成word
            POIFSFileSystem poifs = new POIFSFileSystem();
            DirectoryEntry directory = poifs.getRoot();
            directory.createDocument("WordDocument", bais);

            ostream = new FileOutputStream(filePath + attachID + "." + docFileName);
            poifs.writeFilesystem(ostream);
            bais.close();
            ostream.close();

            File docFile = new File(filePath + attachID + "." + docFileName);

            if(docFile.exists()){
                //获得模块id
                byte mid = 0;
                for (ModuleEnum em : ModuleEnum.values()) {
                    if (em.getName().equals("workflow")) {
                        mid = (byte) em.getIndex();
                    }
                }

                // 保存进数据库
                Attachment attachment = new Attachment();
                attachment.setAttachId(attachID);
                attachment.setModule(mid);
                attachment.setAttachFile(flowRun.getRunName()+".doc");
                attachment.setAttachName(flowRun.getRunName()+".doc");
                attachment.setYm(ym);
                attachment.setAttachSign(new Long(0));
                attachment.setDelFlag((byte) 0);
                attachment.setPosition((byte) 2);
                attachment.setIsImage((byte) 0);
                attachment.setSize(Convert.convertFileSize(docFile.length()));
                attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 把附件信息存储进数据库中
                attachmentMapper.insertSelective(attachment);

                String attUrl = "AID=" + attachment.getAid() + "&" + "MODULE=workflow&" + "COMPANY=" + company + "&" + "YM=" + attachment.getYm() + "&" + "ATTACHMENT_ID=" + attachment.getAttachId() + "&" +
                        "ATTACHMENT_NAME=" + attachment.getAttachName() + "&" + "FILESIZE=" + attachment.getFileSize();

                attachment.setAttUrl(attUrl);


                json.setObject(attachment);
                json.setFlag(0);
                json.setMsg("ok");

            }
        } catch (Exception e) {
            e.getMessage();
            e.printStackTrace();
        } finally {
            try {
                if (bais != null) {
                    bais.close();
                }
            } catch (Exception e) {

            }
            try {
                if (ostream != null) {
                    ostream.close();
                }
            } catch (Exception e) {

            }

        }

        return json;
    }


}
